class Concept < ActiveRecord::Base
  belongs_to :fragment
  # TODO: REFACTOR!  Attributes class should not be called this because the "attributes" word is a reserved word
  has_many :attributes, :dependent => :delete_all

#  TODO: good luck trying to get the has many through working for the concept to concept mappings
#  It's very hard because 1.) concept has many concepts (which is weird)
#                         2.) maps table has non-standard primary key (it's not "concept_id")
#                         3.) maps table uses a composite primary key for concepts
#  has_many :maps, :primary_key => "local_key", :foreign_key => "from_local_key"
#  has_many :core_mappings, :class_name => "Concept", :through => :maps, :source => "to_concept",  :foreign_key => "to_local_key"

  # returns all the mapped concepts.  can be cascaded with a fragment to get all the mapped concepts for a fragment, like:
  # Fragment.find(1).concepts.mapped => returns all the mapped concepts for fragment 1
  named_scope :mapped, {    
    :joins => "JOIN #{Map.table_name} ON #{Concept.table_name}.local_key = #{Map.table_name}.from_local_key AND #{Concept.table_name}.fragment_id = #{Map.table_name}.from_fragment_id",
    :group => "local_key, fragment_id"
  } do
    # override the count method because the default will not appropriately grab unique concepts
    def count
      self.length
    end
  end
  
  named_scope :imported_mappings, {
    :joins => "JOIN #{Map.table_name} ON #{Concept.table_name}.local_key = #{Map.table_name}.from_local_key AND #{Concept.table_name}.fragment_id = #{Map.table_name}.from_fragment_id",
    :conditions => "#{Map.table_name}.is_imported = true",
    :group => "local_key, fragment_id"
  } do
    # override the count method because the default will not appropriately grab unique concepts
    def count
      self.length
    end
  end

  def Concept.max_id
    results = Fragment.connection.execute "SELECT MAX(id) FROM #{Concept.table_name}"
    row = results.fetch_row
    max = row[0].to_i unless row.nil?
    return max
  end

  def mappings
    Concept.find(:all, :joins => "JOIN #{Map.table_name} ON #{Concept.table_name}.local_key = #{Map.table_name}.to_local_key AND #{Concept.table_name}.fragment_id = #{Map.table_name}.to_fragment_id", :conditions => ["#{Map.table_name}.from_local_key = ? AND #{Map.table_name}.from_fragment_id = ?", self.local_key, self.fragment_id], :group => "id")
  end

  # this method returns the mapping details specified in the maps model for the relationship between
  # this instance of Concept and the concept specified in the argument
  def mapping_details_for(concept)
    unless concept.nil?
      Map.find_by_sql ["SELECT * FROM #{Map.table_name} WHERE from_fragment_id = ? AND from_local_key = ? AND to_fragment_id = ? AND to_local_key = ?", self.fragment_id, self.local_key, concept.fragment_id, concept.local_key]
    end
  end

  # this method is another way of viewing this concepts attributes
  # the problem is that "attributes" is a reserved word because it is an attribute of the Object class
  def attrs
    Attribute.find :all, :conditions => {:concept_id => self.id}, :order => "name"
  end

end
